import talib


class Indicator(object):
    def __init__(self, dataframe):
        self.dataframe = dataframe

    def cci(self, period):
        # period: 8, 18, 28, 60
        return talib.CCI(self.dataframe.high, self.dataframe.low, self.dataframe.close, timeperiod=period)

    def stddev(self, period):
        # period: 5, 20
        return talib.STDDEV(self.dataframe.close, timeperiod=period, nbdev=1)

    def var(self, period):
        # period: 5, 20
        return talib.VAR(self.dataframe.close, timeperiod=period, nbdev=1)

    def bolling(self, period):
        # 0: up, 1: mb, 2: lb
        return talib.BBANDS(self.dataframe.close, timeperiod=period, nbdevup=2, nbdevdn=2, matype=0)

    def willr(self, period):
        # period: 14, 28
        return talib.WILLR(self.dataframe.high, self.dataframe.low, self.dataframe.close, timeperiod=period)

    def kdj(self):
        stoch = talib.STOCH(self.dataframe.high, self.dataframe.low, self.dataframe.close, fastk_period=9, slowk_period=5, slowk_matype=1, slowd_period=5, slowd_matype=1)
        return stoch[0], stoch[1], (3 * stoch[0] - 2 * stoch[1])

    def obv(self):
        return talib.OBV(self.dataframe.close, self.dataframe.volume)

    def macd(self):
        # 0: macd, 1: signal, 2:hist
        return talib.MACD(self.dataframe.close, fastperiod=12, slowperiod=26, signalperiod=9)

    def rsi(self, period):
        # period: 12, 14, 21, 25
        return talib.RSI(self.dataframe.close, timeperiod=period)

    def rocp(self, period):
        # period: 1, 2, 3, 4, 5, 21, 63, 125, 250
        return talib.ROCP(self.dataframe.close, timeperiod=period)

    def ma(self, period):
        # period: 5, 10, 20, 60, 120, 250
        return talib.MA(self.dataframe.close, timeperiod=period)

    def sma(self, period):
        # period: 10, 20, 30, 50
        return talib.SMA(self.dataframe.close, timeperiod=period)

    def ema(self, period):
        # period: 5, 10, 12, 20, 26, 50, 100, 200
        return talib.EMA(self.dataframe.close, timeperiod=period)

    def trange(self):
        return talib.TRANGE(self.dataframe.high, self.dataframe.low, self.dataframe.close)

    def atr(self, timeperiod=14):
        return talib.ATR(self.dataframe.high, self.dataframe.low, self.dataframe.close, timeperiod=timeperiod)

    def natr(self, timeperiod=14):
        return talib.NATR(self.dataframe.high, self.dataframe.low, self.dataframe.close, timeperiod=timeperiod)

    def plus_di(self, period):
        # period: 6, 14
        return talib.PLUS_DI(self.dataframe.high, self.dataframe.low, self.dataframe.close, timeperiod=period)

    def minus_di(self, period):
        # period: 6, 14
        return talib.MINUS_DI(self.dataframe.high, self.dataframe.low, self.dataframe.close, timeperiod=period)

    def dx(self, period):
        # period: 6, 14
        return talib.DX(self.dataframe.high, self.dataframe.low, self.dataframe.close, timeperiod=period)

    def adx(self, period):
        # period: 6, 14
        return talib.ADX(self.dataframe.high, self.dataframe.low, self.dataframe.close, timeperiod=period)

    def adxr(self, period):
        # period: 6, 14
        return talib.ADXR(self.dataframe.high, self.dataframe.low, self.dataframe.close, timeperiod=period)

    def trix(self, period):
        # period: 12, 30
        return talib.TRIX(self.dataframe.close, timeperiod=period)

    def slope(self, period):
        # period: 8, 14, 28, 60, 120
        return talib.LINEARREG_SLOPE(self.dataframe.close, timeperiod=period)

    def angle(self, period):
        # period: 8, 14, 28, 60, 120
        return talib.LINEARREG_ANGLE(self.dataframe.close, timeperiod=period)

    def intercept(self, period):
        # period: 8, 14, 28, 60, 120
        return talib.LINEARREG_INTERCEPT(self.dataframe.close, timeperiod=period)

    def tsf(self, period):
        # period: 8, 14
        return talib.TSF(self.dataframe.close, timeperiod=period)

    def apo(self):
        return talib.APO(self.dataframe.close, fastperiod=12, slowperiod=26, matype=0)

    def aroon(self):
        # 0: down, 1: up
        return talib.AROON(self.dataframe.high, self.dataframe.low, timeperiod=14)

    def bop(self):
        return talib.BOP(self.dataframe.open, self.dataframe.high, self.dataframe.low, self.dataframe.close)

    def aroonosc(self, period):
        # period: 8, 14
        return talib.AROONOSC(self.dataframe.high, self.dataframe.low, timeperiod=period)

    def mfi(self, period):
        # period: 8, 14
        return talib.MFI(self.dataframe.high, self.dataframe.low, self.dataframe.close, self.dataframe.volume, timeperiod=period)

    def mom(self, period):
        # period: 10
        return talib.MOM(self.dataframe.close, timeperiod=period)

    def ppo(self):
        return talib.PPO(self.dataframe.close, fastperiod=12, slowperiod=26, matype=0)

    def rocr(self, period):
        # period: 2, 4, 8, 16
        return talib.ROCR(self.dataframe.close, timeperiod=period)

    def stoch(self):
        return talib.STOCH(self.dataframe.high, self.dataframe.low, self.dataframe.close, fastk_period=5, slowk_period=3, slowk_matype=0, slowd_period=3, slowd_matype=0)

    def ultosc(self):
        return talib.ULTOSC(self.dataframe.high, self.dataframe.low, self.dataframe.close, timeperiod1=7, timeperiod2=14, timeperiod3=28)

    def trendline(self):
        return talib.HT_TRENDLINE(self.dataframe.close)

    def sar(self):
        return talib.SAR(self.dataframe.high, self.dataframe.low, acceleration=0, maximum=0)

    def cmo(self, period):
        # period: 14, 28
        return talib.CMO(self.dataframe.close, timeperiod=period)

    def ad(self):
        return talib.AD(self.dataframe.high, self.dataframe.low, self.dataframe.close, self.dataframe.volume)

    def adosc(self):
        return talib.ADOSC(self.dataframe.high, self.dataframe.low, self.dataframe.close, self.dataframe.volume, fastperiod=3, slowperiod=10)

    def dcperiod(self):
        return talib.HT_DCPERIOD(self.dataframe.close)

    def dcphase(self):
        return talib.HT_DCPHASE(self.dataframe.close)

    def inphase(self):
        return talib.HT_PHASOR(self.dataframe.close)[0]

    def quadrature(self):
        return talib.HT_PHASOR(self.dataframe.close)[1]

    def sine(self):
        return talib.HT_SINE(self.dataframe.close)[0]

    def leadsine(self):
        return talib.HT_SINE(self.dataframe.close)[1]

    def trendmode(self):
        return talib.HT_TRENDMODE(self.dataframe.close)

    def beta(self, period):
        # period: 5, 14, 28
        return talib.BETA(self.dataframe.high, self.dataframe.low, timeperiod=period)

    def correl(self, period):
        # period: 14, 30
        return talib.CORREL(self.dataframe.high, self.dataframe.low, timeperiod=period)

    def pbx(self, period):
        return (talib.EMA(self.dataframe.close, timeperiod=period) + talib.MA(self.dataframe.close, timeperiod=period * 2) + talib.MA(self.dataframe.close, timeperiod=period * 4)) / 3

    def avgvol(self, period):
        return talib.MA(self.dataframe.volume, timeperiod=period)


__all__ = [Indicator]
